#include "Mario.h"
#include "Method.h"
#include "PlayState.h"
#include "Bullet.h"
#include "Game.h"

Mario::Mario(float posX, float posY, float width, float height, int kind, Resources* res, int number, int depth)
:GameObject(posX, posY, width, height, res, number, depth)
{
	// Create sprites
	_spriteSmall = new Sprite(_resources->MarioSmall, 5, 5, 0.1f);
	_spriteBig = new Sprite(_resources->MarioBig, 5, 5, 0.1f);
	_spriteFire = new Sprite(_resources->MarioFire, 5, 5, 0.1f);

	// Set current state
	if (kind == 1)
		ChangeState(MARIO_STATE::MARIO_SMALL);
	else if (kind == 2)
		ChangeState(MARIO_STATE::MARIO_BIG);
	else
		ChangeState(MARIO_STATE::MARIO_BIGFIRE);

	// Set value for some properties
	_id = ID::ID_Mario;
	_direction = 1;
	_vel_x = 0;
	_vel_y = 100;
	_acc_x = 0;
	_acc_y = GRAVITY;
	_vel_x_max = 0;
	_is_jumping = false;
	_is_sit = false;

	_old_rect = _rect;

	_old_x = _pos_x;
	_old_y = _pos_y;

	_isWin = false;
	_isChangeMap = false;
	_imperishable = false;
	_count_time = 0;
}


Mario::~Mario()
{
	delete _spriteSmall;
	delete _spriteFire;
	delete _spriteBig;
}

/*************************************************************
* Mario::ProcessInput
* Process keyboard to move or jump Mario
**************************************************************/
void Mario::ProcessInput(Input* input)
{
	if (_state == MARIO_STATE::MARIO_DIE)
		return;

	switch (input->OnKeyDown())
	{
	case DIK_Z:
		if (_is_jumping == false)
		{
			_is_jumping = true;
			_vel_y = -MARIO_VY_MAX;

			if (_onSound)
				_resources->_audio->PlaySoundA(_resources->Jump);
		}
		break;
	case DIK_X:
		if (_state == MARIO_STATE::MARIO_BIGFIRE)
		{

			Bullet* bullet = new Bullet(_direction == 1 ? _pos_x + _width : _pos_x - _width, _pos_y + _height / 3, 25, 25, _resources, _direction, 0);
			ListObjects.push_back(bullet);

			if (_onSound)
				_resources->_audio->PlaySoundA(_resources->FireBall);
		}
		break;
	case DIK_Q:
		ChangeState(MARIO_STATE::MARIO_SMALL);
		break;
	case DIK_W:
		ChangeState(MARIO_STATE::MARIO_BIG);
		break;
	case DIK_E:
		ChangeState(MARIO_STATE::MARIO_BIGFIRE);
		break;
	default:
		break;
	}


	// Sit
	if (input->KeyDown(DIK_DOWN))
	{
		_is_sit = true;
	}
	else
	{
		_is_sit = false;

		// Run Right
		if (input->KeyDown(DIK_RIGHT))
		{
			// Set acceleration and max velocity
			_acc_x = GRAVITY / 4;

			_vel_x_max = MARIO_VX_MAX;

			_direction = 1;
		}

		// Run Left
		if (input->KeyDown(DIK_LEFT))
		{
			_acc_x = -GRAVITY / 4;
			_vel_x_max = MARIO_VX_MAX;

			_direction = -1;
		}

		// Key right and key left don't press
		if (!input->KeyDown(DIK_LEFT) && !input->KeyDown(DIK_RIGHT))
		{
			// Set mario idle
			if (_vel_x > -30 && _vel_x < 30)
			{
				_vel_x = 0;
				_acc_x = 0;
			}
		}
	}
}

/********************************************************************************************************
*
* Mario::Update
* Update position, animation of Mario
* Check collision with other objects
* Param: time
* Param listObj- list objects that can make mario die or change state
* Ex: Goomba, turtle, mushroom, star...
* Param stListObj- list static objects. Ex: Brick, land, stone...
*
**********************************************************************************************************/
void Mario::Update(float time, QNode* &Tree)
{
	vector<GameObject*>  listObj, stListObj;

	Method::GetObjectInViewport(_rect, Tree, listObj, stListObj);

	listObj.insert(listObj.end(), ListObjects.begin(), ListObjects.end());

	// Apply physics to Mario
	Move(time, stListObj);

	if (_pos_x < 20) _pos_x = 20;

	if (_pos_y < -50 && _state != MARIO_STATE::MARIO_DIE)
	{
		ChangeState(MARIO_STATE::MARIO_DIE);
	}

	if (_state == MARIO_STATE::MARIO_DIE && _pos_y < -50)
		_isAlive = false;

	if (_state == MARIO_STATE::MARIO_DIE)
		return;

	if (_isChangeMap == true && _pos_y < 100)
		_isWin = true;

	if (_imperishable == true)
	{
		_count_time++;
		if (_count_time > 1200)
		{
			_imperishable = false;
			_count_time = 0;
		}
	}

	//=========================================================================================================
	int n = listObj.size();

	for (int i = 0; i < n; i++)
	{
		if (listObj[i]->ID() != this->_id)
		{
			float CollisionTime;
			// Check collision and get direction collision
			DirCollision dir = Method::IsCollision(this, listObj[i], CollisionTime);

			if (dir != DirCollision::NONE)
			{
				switch (listObj[i]->ID())
				{
				case ID::ID_Goomba:
					
					if (_imperishable == true)
					{
						GAME_SCORE += 100;
						ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));
						listObj[i]->ChangeState(GOOMBA_STATE::GOOMBA_FALL);
						break;
					}
					
					
					/************************************
					* Goomba State
					*		GOOMBA_NORMAL	= 0
					*		GOOMBA_DIE		= 1
					*		GOOMBA_FALL		= 2
					*************************************/
					if ((dir == DirCollision::LEFT || dir == DirCollision::RIGHT || dir == DirCollision::TOP)
						&& listObj[i]->GetState() != GOOMBA_STATE::GOOMBA_FALL && listObj[i]->GetState() != GOOMBA_STATE::GOOMBA_DIE)
					{
						if (_state == MARIO_STATE::MARIO_BIG || _state == MARIO_STATE::MARIO_BIGFIRE)
						{
							ChangeState(MARIO_STATE::MARIO_SMALL);
						}
						else
						{
							ChangeState(MARIO_STATE::MARIO_DIE);
						}
					}
					else if (listObj[i]->GetState() == 0)	// if direction = BOTTOM
					{

						_is_jumping = true;
						_acc_y = GRAVITY;
						_vel_y = -MARIO_VY_MAX + MARIO_VY_MEDIUM;
						listObj[i]->ChangeState(GOOMBA_STATE::GOOMBA_DIE);			// set state gooba = DIE
						
						if (_onSound)
							_resources->_audio->PlaySoundA(_resources->Mip);
						GAME_SCORE += 100;
						ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));


					}
					break;
					/**********************************************************************************************************************/
				case ID::ID_Koopa:

					if (_imperishable == true)
					{
						GAME_SCORE += 100;
						ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));
						listObj[i]->ChangeState(KOOPA_STATE::KOOPA_FALL);
						break;
					}

					if (listObj[i]->GetState() == KOOPA_STATE::KOOPA_FALL) // Turtle is falling
						break;

					if (dir == DirCollision::LEFT || dir == DirCollision::RIGHT || dir == DirCollision::TOP)
					{
						if (_state == MARIO_STATE::MARIO_BIG || _state == MARIO_STATE::MARIO_BIGFIRE)
						{
							ChangeState(MARIO_STATE::MARIO_SMALL);
						}
						else
						{	
							ChangeState(MARIO_STATE::MARIO_DIE);
						}
					}
					else	// Direction = BOTTOM
					{
						if (listObj[i]->GetState() == KOOPA_STATE::KOOPA_NORMAL || listObj[i]->GetState() == KOOPA_STATE::KOOPA_ROTATION)
						{
							_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime);
							ResetRect();
							_is_jumping = true;
							_acc_y = GRAVITY;
							_vel_y = -MARIO_VY_MAX + MARIO_VY_MEDIUM;
							listObj[i]->ChangeState(KOOPA_STATE::KOOPA_IDLE);
							
							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Mip);
						}
						else if (listObj[i]->GetState() == KOOPA_STATE::KOOPA_IDLE)
						{
							_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime);
							ResetRect();
							_is_jumping = true;
							_acc_y = GRAVITY;
							_vel_y = -MARIO_VY_MAX + MARIO_VY_MEDIUM;
							listObj[i]->ChangeState(KOOPA_STATE::KOOPA_ROTATION);
							
							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Mip);
						}
					}
					break;
					/**********************************************************************************************************************/
				case ID::ID_MushRed:
					GAME_SCORE += 100;
					ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));
					if (_state == MARIO_STATE::MARIO_SMALL)
						ChangeState(MARIO_STATE::MARIO_BIG);
					else if (_state == MARIO_STATE::MARIO_BIG)
					{
						//if (_i_live < 4) _i_live++;
					}
					else
					{
						// Xu ly
					}

					listObj[i]->SetIsAlive(false);

					if (_onSound)
						_resources->_audio->PlaySoundA(_resources->PowerUp);
					break;
					/**********************************************************************************************************************/
				case ID::ID_MushGreen:
					GAME_SCORE += 100;
					ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));
					if (_state == MARIO_STATE::MARIO_SMALL)
						ChangeState(MARIO_STATE::MARIO_BIG);
					else if (_state == MARIO_STATE::MARIO_BIG)
					{
						//if (_i_live < 4) _i_live++;
						// thong bao up
					}
					else
					{
						// Xu ly
					}

					listObj[i]->SetIsAlive(false);

					if (_onSound)
						_resources->_audio->PlaySoundA(_resources->BonusRise);
					break;
					/**********************************************************************************************************************/
				case ID::ID_Flower:
					GAME_SCORE += 100;
					ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));

					if (_state == MARIO_STATE::MARIO_SMALL)
					{
						ChangeState(MARIO_STATE::MARIO_BIG);
					}
					else if (_state == MARIO_STATE::MARIO_BIG)
					{
						ChangeState(MARIO_STATE::MARIO_BIGFIRE);
					}

					listObj[i]->SetIsAlive(false);

					if (_onSound)
						_resources->_audio->PlaySoundA(_resources->PowerUp);
					break;
					/**********************************************************************************************************************/
				case ID::ID_Star:
					listObj[i]->SetIsAlive(false);
					GAME_SCORE += 200;
					ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 200));
					
					if (_onSound)
						_resources->_audio->PlaySoundA(_resources->BonusRise);
					_imperishable = true;
					break;
					/**********************************************************************************************************************/
				case ID::ID_EatFlower:
					if (_imperishable == true)
					{
						GAME_SCORE += 100;
						ListObjects.push_back(new Score(listObj[i]->PosX(), listObj[i]->PosY() + 50, 15, 16, _resources, 100));
						listObj[i]->SetIsAlive(false);
						break;
					}

					if (_state == MARIO_STATE::MARIO_BIG || _state == MARIO_STATE::MARIO_BIGFIRE)
					{
						ChangeState(MARIO_STATE::MARIO_SMALL);
					}
					else
					{
						ChangeState(MARIO_STATE::MARIO_DIE);
					}
					break;
				case ID::ID_Boss:
					if (_state == MARIO_STATE::MARIO_BIG || _state == MARIO_STATE::MARIO_BIGFIRE)
					{
						ChangeState(MARIO_STATE::MARIO_SMALL);
					}
					else
					{
						ChangeState(MARIO_STATE::MARIO_DIE);
					}
					break;
				default:
					break;
				}
			}
		}
	}
	//=========================================================================================================

	// Create inertia
	if (_vel_x > 0)
		_acc_x = -GRAVITY / 2;
	else if (_vel_x < 0)
		_acc_x = GRAVITY / 2;

	// Update Animation
	UpdateAnimation(time);
}

/************************************************************************************************
*
*	Render
*
*************************************************************************************************/
void Mario::Render(LPD3DXSPRITE spriteHandler, Viewport* viewport)
{
	if (_imperishable == true)
	{
		if (_direction == 1)
			_sprite->Render(spriteHandler, _pos_x, _pos_y + 20, false, viewport);
		else
			_sprite->Render(spriteHandler, _pos_x, _pos_y + 20, true, viewport);
	}

	if (_direction == 1)
		_sprite->Render(spriteHandler, _pos_x, _pos_y, false, viewport);
	else
		_sprite->Render(spriteHandler, _pos_x, _pos_y, true, viewport);
}

/************************************************************************************************
*
*	Move
*	Update position and check collision with static object
*
*************************************************************************************************/
void Mario::Move(float time, vector<GameObject*> &listObj)
{
	// Save old position
	_old_x = _pos_x;
	_old_y = _pos_y;

	// Upate Velocity X
	_vel_x += _acc_x * time;

	// Limit velocity in the range [-Vmax; Vmax]
	if (_vel_x > _vel_x_max)
		_vel_x = _vel_x_max;
	else if (_vel_x < -_vel_x_max)
		_vel_x = -_vel_x_max;

	// Update position X
	_pos_x += _vel_x * time + 0.5f * _acc_x * time * time;

	// Update velocity Y
	_vel_y += _acc_y * time;

	// Update position Y
	_pos_y -= _vel_y * time + 0.5f *_acc_y * time * time;

	//if (_pos_y < 85) _pos_y = 85;
	// Save Old Rect
	_old_rect = _rect;

	// Reset Rect
	ResetRect();

	// Check Mario die
	if (_pos_y < 0 && _state != MARIO_STATE::MARIO_DIE)
		ChangeState(MARIO_STATE::MARIO_DIE);

	// If Mario was died, not check collision
	if (_state == MARIO_STATE::MARIO_DIE)
		return;

	// List  Object have collision with this
	vector<GameObject*> listCollision;

	int n = listObj.size();
	for (int i = 0; i < n; i++)
	{
		if (listObj[i]->ID() != this->_id)
		{
			float CollisionTime;
			// Check collision and get direction collision
			DirCollision dir = Method::IsCollision(this, listObj[i], CollisionTime);

			// Not collision
			if (dir != DirCollision::NONE)
			{
				listObj[i]->TimeCollision = CollisionTime;
				listCollision.push_back(listObj[i]);
			}
		}
	}

	// Sort List Objects have collision by TimeCollision
	// Object have TimeCollision minimum will happen collision first.
	std::sort(listCollision.begin(), listCollision.end(), Method::MinDistance);
	
	if (listCollision.size() > 3)
	{
		int i = 0;
	}
	for (int i = 0; i < listCollision.size(); i++)
	{
		float CollisionTime;
		DirCollision dir = Method::IsCollision(this, listCollision[i], CollisionTime);

		// Have collision
		switch (listCollision[i]->ID())
		{
		case ID::ID_Brick:
			// if state of brick is break, don't check collision with it
			if (listCollision[i]->GetState() == BRICK_STATE::BRICK_BREAK)
				break;

			if (dir == DirCollision::LEFT || dir == DirCollision::RIGHT)
			{
				_vel_x = _acc_x = 0;
				_pos_x = _old_x + (_pos_x - _old_x) * CollisionTime;
				ResetRect();
			}
			else if (dir == DirCollision::TOP)
			{
				if (_state == MARIO_STATE::MARIO_SMALL)
				{
					// Brick Move Up
					listCollision[i]->ChangeState(BRICK_STATE::BRICK_MOVEUP);
					_acc_y = GRAVITY;
					_vel_y = MARIO_VY_MEDIUM;
					_pos_y = _old_y + (_pos_y - _old_y) * CollisionTime - 5;
					ResetRect();
					_resources->_audio->PlaySoundA(_resources->Bump);
				}
				else
				{
					// Brick break
					listCollision[i]->ChangeState(BRICK_STATE::BRICK_BREAK);
					_acc_y = GRAVITY;
					_vel_y = MARIO_VY_MEDIUM;
					_pos_y = _old_y + (_pos_y - _old_y) * CollisionTime - 5;
					ResetRect();
					_resources->_audio->PlaySoundA(_resources->BrickBreaked);
					GAME_SCORE += 50;

					// Add score
					ListObjects.push_back(new Score(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 15, 16, _resources, 50));
				}
			}
			else if (dir == DirCollision::BOTTOM)
			{
				_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime + 2);
				ResetRect();

				_is_jumping = false;
				_vel_y = 0;
			}
			break;
			/**************************************************************************************************/
		case ID::ID_QBrick:
			if (dir == DirCollision::LEFT || dir == DirCollision::RIGHT)
			{
				_vel_x = _acc_x = 0;
				_pos_x = _old_x + (_pos_x - _old_x) * CollisionTime;
				ResetRect();
			}
			else if (dir == DirCollision::TOP)
			{
				_acc_y = GRAVITY;
				_vel_y = MARIO_VY_MEDIUM;
				_pos_y = _old_y + (_pos_y - _old_y) * CollisionTime;
				ResetRect();

				if (_onSound)
					_resources->_audio->PlaySoundA(_resources->Jump);
				
				// Add coin
				if (listCollision[i]->GetState() == QBRICK_STATE::QBRICK_NORMAL)
				{
					GameObject* og = NULL;
					switch (listCollision[i]->MoreOver())
					{
						case ID::ID_Coin:
							og = new Coin(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 50, 50, _resources, -1, 2);
							og->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);
							GAME_SCORE += 100;

							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->CoinS);
							ListObjects.push_back(new Score(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 15, 16, _resources, 100));
							GAME_COIN++;
							break;
						case ID::ID_MushGreen:
							og = new Mushroom(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 50, 45, _resources, ID::ID_MushGreen, -1, 2);
							og->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);

							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Bump);
							break;
						case ID::ID_MushRed:
							og = new Mushroom(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 50, 45, _resources, ID::ID_MushRed, -1, 2);
							og->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);

							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Bump);
							break;
						case ID::ID_Flower:
							og = new Mushroom(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 50, 45, _resources, ID::ID_Flower, -1, 2);
							og->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);

							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Bump);
							break;
						case ID::ID_Star:
							og = new Star(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 50, 45, _resources, -1, 2);
							og->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);

							if (_onSound)
								_resources->_audio->PlaySoundA(_resources->Bump);
							break;
						default:
							break;
					}
					if (og != NULL)
						ListObjects.push_back(og);
				}		

				// Change state QBrick
				listCollision[i]->ChangeState(QBRICK_STATE::QBRICK_MOVEUP);
			}
			else if (dir == DirCollision::BOTTOM)
			{
				_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime + 2);
				ResetRect();

				_is_jumping = false;
				_vel_y = 0;

				
			}
			break;
			/**************************************************************************************************/
		case ID::ID_Coin:
			if (listCollision[i]->GetState() == COIN_STATE::COIN_NORMAL)
			{
				listCollision[i]->SetIsAlive(false);

				if (_onSound)
					_resources->_audio->PlaySoundA(_resources->CoinS);
				GAME_COIN++;
				GAME_SCORE += 100;
				ListObjects.push_back(new Score(listCollision[i]->PosX(), listCollision[i]->PosY() + 50, 15, 16, _resources, 100));
			}
			break;
			/**************************************************************************************************/
		case ID::ID_Land:
		case ID::ID_StoneA:
		case ID::ID_StoneB:
		case ID::ID_Pipe1:
		case ID::ID_Pipe2:
		case ID::ID_Pipe3:
		case ID::ID_PipeSpecial:
			if (dir == DirCollision::LEFT || dir == DirCollision::RIGHT)
			{
				_vel_x = _acc_x = 0;
				_pos_x = _old_x + (_pos_x - _old_x) * CollisionTime;
				ResetRect();
	
			}
			else if (dir == DirCollision::TOP)
			{
				_acc_y = GRAVITY;
				_vel_y = MARIO_VY_MEDIUM;
				_pos_y = _old_y + (_pos_y - _old_y) * CollisionTime;
				ResetRect();
			}
			else if (dir == DirCollision::BOTTOM)
			{
				_vel_y = 0;
				_is_jumping = false;
				_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime + 2);
				ResetRect();
			}

			if (listCollision[i]->ID() == ID::ID_PipeSpecial && _is_sit == true
				&& (_pos_x > listCollision[i]->PosX() - 10) && _pos_x < listCollision[i]->PosX() + 10)
			{
				_pos_y -= 3;
				_acc_y /= 20;
				_isChangeMap = true;
			}
				
			break;
		case ID::ID_Ladder:
			if (dir == DirCollision::BOTTOM)
			{
				_vel_y = 0;
				_is_jumping = false;
				_pos_y = (int)(_old_y + (_pos_y - _old_y) * CollisionTime);
				ResetRect();
			}
			break;
		case ID::ID_House:

			if (_onSound)
				_resources->_audio->LoopSound(_resources->WinState);
			_isChangeMap = true;
			_isWin = true;
			break;
		default:
			break;
		}
	}

}

/************************************************************************************************
*
*	UpdateAnimation
*
*************************************************************************************************/
void Mario::UpdateAnimation(float time)
{
	switch (_state)
	{
	case MARIO_STATE::MARIO_SMALL:
	case MARIO_STATE::MARIO_BIG:
	case MARIO_STATE::MARIO_BIGFIRE:
		if (_is_jumping == false)		// Mario is idle or run, not jump
		{
			if (_vel_x != 0)				// Mario is running
			{
				if (_sprite_index != 2)	// don't sprite small
					_sprite->Next(2, 3, time);
				else
					_sprite->Next(0, 1, time);
			}
			else						// Mario is idling
			{
				_sprite->Next(0);
			}
		}
		else if (_vel_y < 0)				// Mario is jumping
		{
			if (_sprite_index != 2)	// don't sprite small
				_sprite->Next(1);
			else
				_sprite->Next(2);
		}
		break;
	case MARIO_STATE::MARIO_DIE:

		break;
	default:
		break;
	}
}


/************************************************************************************************
*
*	ChangeState
*
*************************************************************************************************/
void Mario::ChangeState(char state)
{
	_state = state;

	switch (_state)
	{
	case MARIO_STATE::MARIO_SMALL:
		_sprite = _spriteSmall;
		_sprite_index = 2;
		this->Width(40);
		this->Height(60);
		_vel_y = -MARIO_VY_MAX / 2;
		break;
	case MARIO_STATE::MARIO_BIG:
		_sprite = _spriteBig;
		_sprite_index = 1;
		this->Width(40);
		this->Height(85);
		_pos_y += 30;
		_vel_y = -MARIO_VY_MAX / 2;
		break;
	case MARIO_STATE::MARIO_BIGFIRE:
		_sprite = _spriteFire;
		_sprite_index = 1;
		_pos_y += 30;
		this->Width(40);
		this->Height(85);
		_vel_y = -MARIO_VY_MAX / 2;
		break;
	case MARIO_STATE::MARIO_DIE:
		if (_state != MARIO_STATE::MARIO_SMALL)
			_sprite = _spriteSmall;

		_sprite->Next(4);

		if (_onSound)
			_resources->_audio->PlaySoundA(_resources->Death);
		
		_is_jumping = true;
		_acc_y = GRAVITY;
		_vel_y = -MARIO_VY_MAX;
		_vel_x = 0;
		_acc_x = 0;
		break;
	default:
		break;
	}
}